
import { getLeftMenu } from '@/framework/api/menu'
import AppView from '@/framework/views/layouts/AppView'
import { isExternal } from '@/framework/utils/validate'
import { showScreenLoading, hideScreenLoading } from 'DQBasic-vue-component'
import IframePageView from '@/framework/views/layouts/IframePageView'
import store from '@/store'
import { asyncRoutes, constantRoutes } from '@/framework/router'
import { resetRouter } from '@/router'
import { upperCamelCase } from '@/framework/utils/index'

const LowCodeDefalutMenu = [
  {
    appCode: 'devCenter',
    component: (resolve) => require(['@/framework/views/developer-center/application-center/reviewTemplate.vue'], resolve),
    fullScreen: 'Y',
    hide: false,
    icon: 'el-icon-phone-outline',
    menuCode: 'VisitorTemplate',
    menuType: 'C',
    multiTab: 'Y',
    path: '/home/visitorTemplate',
    shortcut: 'N',
    title: '门户_访问者模版',
    visible: 'N'
  }, {
    appCode: 'devCenter',
    component: (resolve) => require(['@/framework/views/developer-center/devWorkflow/flowDetail/index.vue'], resolve),
    fullScreen: 'Y',
    hide: false,
    icon: 'el-icon-setting',
    menuCode: 'LowCodeProcessDetail',
    menuType: 'C',
    multiTab: 'N',
    path: '/home/lowCodeFlowDetail',
    remark: null,
    shortcut: 'N',
    title: '开发中心流程详情',
    visible: 'N'
  }
]
// 遍历应用数据
function generAppMenu(routes, data, appRoutes) {
  let firstLowCodeApp = true // 防止多次创建LowCodeDefalutMenu菜单
  for (const item of data) { // 遍历应用
    if (item.appSource === 3) { // ”开发中心-创建的应用“的菜单，不用动态生成路由；需要生成LowCodeDefalutMenu中的路由
      if (firstLowCodeApp) {
        routes.push(...LowCodeDefalutMenu)
        firstLowCodeApp = false
      }
      break
    }
    const appRoute = []

    if (item.children) {
      generaMenu(appRoute, item.children, [{
        meta: {
          title: item.title
        },
        path: item.path
      }], true) // 生成当前应用的路由菜单
    }
    for (const app of appRoute) {
      routes.push(app)
    }
    appRoutes.push({
      path: item.path,
      name: item.title,
      appCode: item.appCode,
      hidden: item.visible === 'N',
      icon: item.icon,
      children: appRoute,
      meta: { title: item.title, icon: item.icon, hidden: item.visible === 'N', multiTab: item.multiTab, fullScreen: item.fullScreen }
    })
  }
}
// 遍历菜单数据
function generaMenu(routes, data, parentTitle, isFirstMenu) {
  // 分应用路由
  if (data != null) {
    // 遍历后台返回的菜单路由
    data.forEach((item) => {
      let menu = {}
      // 内链地址
      if (item.component && (item.component.startsWith('/') || isExternal(item.component))) {
        menu = {
          path: item.path,
          component: IframePageView,
          name: upperCamelCase(item.menuCode),
          meta: { title: item.title, icon: item.icon, parentTitle, multiTab: item.multiTab, fullScreen: item.fullScreen },
          hidden: item.visible === 'N',
          props: {
            url: item.component,
            id: item.path
          }
        }
      } else if (item.path && isExternal(item.path)) { // 外链地址
        menu = {
          path: item.path,
          hidden: item.visible === 'N',
          meta: { title: item.title, icon: item.icon, multiTab: item.multiTab, fullScreen: item.fullScreen }
        }
      // } else if (item.path === '/reportDesign' || item.path === '/design' || item.path === '/flowDetail') {
      } else if (item.fullScreen && item.fullScreen === 'Y') {
        const temp = {
          path: item.path,
          component: (resolve) => require([`@/${item.component}`], resolve), // 需要让后台处理layout
          name: upperCamelCase(item.menuCode),
          meta: { title: item.title, icon: item.icon, parentTitle, noCache: false, hidden: item.visible === 'N', appCode: item.appCode, multiTab: item.multiTab, fullScreen: item.fullScreen },
          hidden: item.visible === 'N',
          menuType: item.menuType,
          appCode: item.appCode,
          children: []
        }
        // menu = {
        //     menuType: 'layout', // 默认
        //     path: '/selfLayout' + temp.path,
        //     component: (resolve) => require([`@/framework/layout`], resolve),
        //     children: [temp]
        //   }
        menu = temp
      } else { // 组件
        const temp = {
          path: item.path,
          component: item.component ? (resolve) => require([`@/${item.component === 'layout' ? 'framework/layout' : item.component}`], resolve) : AppView, // 需要让后台处理layout
          name: upperCamelCase(item.menuCode),
          meta: { title: item.title, icon: item.icon, parentTitle, noCache: false, hidden: item.visible === 'N', appCode: item.appCode, multiTab: item.multiTab, fullScreen: item.fullScreen },
          hidden: item.visible === 'N',
          menuType: item.menuType,
          appCode: item.appCode,
          children: []
        }
        //  应用下一级菜单， 全屏展示的处理方式
        // if (item.path === '/reportDesign' || item.path === '/design' || item.path === '/flowDetail') {
        if (item.fullScreen && item.fullScreen === 'Y') {
          menu = temp
        } else if (parentTitle && !item.children && isFirstMenu) { // 应用下一级菜单， 不全屏的处理方式  手动嘉儒layout
          menu = {
            menuType: 'layout', // 默认
            path: `/selfLayout${temp.path}`,
            component: (resolve) => require(['@/framework/layout'], resolve),
            children: [temp]
          }
        } else { // 常规方式
          menu = temp
        }
      }

      if (item.children) {
        generaMenu(menu.children, item.children, [...parentTitle, ...[{
          meta: {
            title: item.title
          },
          path: item.path
        }]])
      }
      if (!routes) {
        routes = []
      }
      routes.push(menu)
    })
  }
}
/**
 * @description 扁平化数组对象(主要用来处理路由菜单)
 * @param {Array} menuList 所有菜单列表
 * @return array
 */
export function getFlatArr(menuList) {
  // const newMenuList = JSON.parse(JSON.stringify(menuList))
  const newMenuList = menuList
  return newMenuList.reduce((pre, current) => {
    let flatArr = []
    if (current.menuType === 'layout') {
      flatArr = [...pre, current]
    } else if (current.menuType === 'M') {
      flatArr = [...pre, current]
      if (current.children) flatArr = [...flatArr, ...getFlatArr(current.children)]
    } else {
      flatArr = [...pre, {
        appCode: 'all',
        children: [
          current
        ],
        component: (resolve) => require(['@/framework/layout'], resolve),
        hide: false,
        menuType: 'M',
        isAddLayout: true,
        path: '/all'
      }]
    }
    return flatArr
  }, [])
}
/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some((role) => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []
  routes.forEach((route) => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: [],
  currentRoutes: [],
  currentAppPath: '',
  appRoutes: []
}

const mutations = {

  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  },
  SET_CURRENT_ROUTES: (state, currentRoutes) => {
    state.currentRoutes = currentRoutes
  },
  SET_APP_ROUTES: (state, appRoutes) => {
    state.appRoutes = appRoutes
  },
  SET_CURRENT_APP_PATH: (state, currentAppPath) => {
    state.currentAppPath = currentAppPath
  }
}
const whiteList = ['/affairManage', '/client1', '/user', '/permission', '/log', '/notice']
const actions = {
  // 设置当前路由
  setCurrentRoutes({ commit }, currentRoutes) {
    commit('SET_CURRENT_ROUTES', currentRoutes)
  },
  setCurrentAppPath({ commit }, currentAppPath) {
    commit('SET_CURRENT_APP_PATH', currentAppPath)
  },
  // 生成所有路由
  generateRoutes({ commit }, { roles, currentPath }) {
    return new Promise((resolve) => {
      const loadMenuData = []
      const loadMenuDataAll = []
      resetRouter()
      // 处理白名单  本地存的路由要考虑
      getLeftMenu({ antdvRouter: currentPath || null }).then((resp) => {
        if (resp.code !== '00000') {
          this.$message({
            message: '菜单数据加载异常',
            type: 0
          })
        } else {
          // 所有应用的菜单
          const dataList = resp.data
          let data = []
          let dataAll = []
          data = dataList.select
          dataAll = dataList.all
          if (document.body.getBoundingClientRect().width < 768) {
            dealMobileMenu(data) // 处理移动端菜单
          }
          Object.assign(loadMenuData, data)
          Object.assign(loadMenuDataAll, dataAll)
          asyncRoutes.length = 0
          const asyncRoutesAll = JSON.parse(JSON.stringify(asyncRoutes))
          const appRoutes = []
          const appRoutesAll = []

          generAppMenu(asyncRoutes, loadMenuData, appRoutes)
          generAppMenu(asyncRoutesAll, loadMenuDataAll, appRoutesAll)
          let accessedRoutes
          if (roles.includes('superAdmin')) {
            accessedRoutes = asyncRoutesAll || []
          } else {
            accessedRoutes = filterAsyncRoutes(asyncRoutesAll, roles)
          }

          if (!appRoutes || appRoutes.length === 0) {
            commit('SET_APP_ROUTES', [])
            store.dispatch('settings/setAppCode', null)
            commit('SET_CURRENT_ROUTES', []) // 根据当前导航模式设置当前路由
          } else {
            // 2.3版本只有一个应用  所以取appRoutes[0].children
            commit('SET_APP_ROUTES', appRoutes[0]?.children)
            commit('SET_CURRENT_ROUTES', appRoutes[0]?.children) // 根据当前导航模式设置当前路由
          }
          if (process.env.VUE_APP_PAGE_CACHE === 'true') {
            // 扁平化路由结构   删除多余子集路由   为了支持多级路由缓存
            const levelMenuArr = getFlatArr(accessedRoutes)
            levelMenuArr.forEach((element) => {
              if (!element.isAddLayout && element.menuType !== 'layout') {
                element.children && delete element.children
              }
            })
            commit('SET_ROUTES', levelMenuArr)
            resolve(levelMenuArr)
          } else {
            commit('SET_ROUTES', accessedRoutes)
            resolve(accessedRoutes)
          }
        }
      })
    })
  },
  /**
   * 点击浏览器返回按钮时  处理菜单显示
   * @returns
   */
  dealBackGenerateRoutes({ commit }, { currentPath }) {
    showScreenLoading()
    return new Promise((resolve) => {
      const loadMenuData = []
      // 处理白名单  本地存的路由要考虑
      getLeftMenu({ antdvRouter: currentPath || null }).then((resp) => {
        if (resp.code !== '00000') {
          this.$message({
            message: '菜单数据加载异常',
            type: 0
          })
        } else {
          // 所有应用的菜单
          const dataList = resp.data
          let data = []
          data = dataList.select
          if (document.body.getBoundingClientRect().width < 768) {
            dealMobileMenu(data) // 处理移动端菜单
          }
          Object.assign(loadMenuData, data)
          asyncRoutes.length = 0
          const appRoutes = []

          generAppMenu(asyncRoutes, loadMenuData, appRoutes)
          if (!appRoutes || appRoutes.length === 0) {
            commit('SET_APP_ROUTES', [])
            store.dispatch('settings/setAppCode', null)
            commit('SET_CURRENT_ROUTES', []) // 根据当前导航模式设置当前路由
          } else {
            // 2.3版本只有一个应用  所以取appRoutes[0].children
            commit('SET_APP_ROUTES', appRoutes[0]?.children)
            commit('SET_CURRENT_ROUTES', appRoutes[0]?.children) // 根据当前导航模式设置当前路由
          }
          hideScreenLoading()
        }
      })
    })
  }
}
function dealMobileMenu(arr) {
  arr.forEach((element) => {
    element.children = element.children.filter((menuItem) => {
      return whiteList.indexOf(menuItem.path) > -1
    })
  })
//  return JSON.parse(JSON.stringify(arr))
}
// function findAppCode(dataList, pathname) {
//   for (const item of dataList) {
//     if (!item.children) {
//       if (item.path == pathname) {
//         return item.appCode
//       }
//     } else {
//       const res = findAppCode(item.children, pathname)
//       if (res) {
//         return res
//       }
//     }
//   }
//   return null
// }
export default {
  namespaced: true,
  state,
  mutations,
  actions
}
